package com.leyou.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.Mapper.SkuMapper;
import com.leyou.Mapper.SpuDetailMapper;
import com.leyou.Mapper.SpuMapper;
import com.leyou.Mapper.StockMapper;
import com.leyou.PageResult;
import item.pojo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsService {
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private StockMapper stockMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;

    public PageResult<SpuBo> uerySpuByPageAndSort(Integer page, Integer rows, Boolean saleable, String key) {
        //分页 每页最多100条
        PageHelper.startPage(page,Math.min(rows,100));
        //创建查询条件
        Example example=new Example(Spu.class);
        Example.Criteria criteria=example.createCriteria();
        // 是否过滤上下架
        if(saleable!=null){
            criteria.orEqualTo("saleable",saleable);
        }
        // 是否模糊查询
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        Page<Spu> pageInfo=(Page<Spu>) this.spuMapper.selectByExample(example);

        List<SpuBo> list= pageInfo.getResult().stream().map(spu -> {
            // 把spu变为 spuBo
            SpuBo spuBo = new SpuBo();
            // 属性拷贝
            BeanUtils.copyProperties(spu, spuBo);

            // 2、查询spu的商品分类名称,要查三级分类
            List<String> names = this.categoryService.queryNamesByIds(
                    Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            // 将分类名称拼接后存入
            spuBo.setCname(StringUtils.join(names, "/"));

            // 3、查询spu的品牌名称
            Brand brand = this.brandService.queryBrandById(spu.getBrandId());

            spuBo.setBname(brand.getName());

            return spuBo;

        }).collect(Collectors.toList());

        return new PageResult<>(pageInfo.getTotal(), list);
    }

    @Transactional
    public void saveGoods(SpuBo spuBo) {
        //保存spu属性
        spuBo.setSaleable(true);
        spuBo.setValid(true);
        spuBo.setCreateTime(new Date());
        spuBo.setLastUpdateTime(spuBo.getCreateTime());
        //保存sku表
        this.spuMapper.insert(spuBo);

        //保存SpuDetail的属性，并插入表
        spuBo.getSpuDetail().setSpuId(spuBo.getId());
        this.spuDetailMapper.insert(spuBo.getSpuDetail());//通过Spu获取SpuDetail对象

        spuBo.getSkus().forEach(sku->{
            sku.setSpuId(spuBo.getId());
            sku.setCreateTime(spuBo.getCreateTime());
            sku.setLastUpdateTime(spuBo.getLastUpdateTime());
            //保存sku
            this.skuMapper.insert(sku);

            //保存stock表
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            this.stockMapper.insert(stock);
        });
        amqpTemplate.convertAndSend("item.insert",spuBo.getId());
    }

    public SpuDetail querySpuDetailById(Long id) {
        return this.spuDetailMapper.selectByPrimaryKey(id);
    }

    public List<Sku> querySkuBySpuId(Long id) {
        // 查询sku（存在多个，结果为集合）
        Sku record = new Sku();
        record.setSpuId(id);
        List<Sku> skus = this.skuMapper.select(record);
        // 同时查询出库存
        for (Sku sku : skus) {
            sku.setStock(this.stockMapper.selectByPrimaryKey(sku.getId()).getStock());
        }
        return skus;
    }

    @Transactional
    public void updateGoods(SpuBo spuBo) {
        //其他属性可能变或不变，但是修改时间一定改变
        spuBo.setLastUpdateTime(new Date());

        //直接修改spu
        this.spuMapper.updateByPrimaryKeySelective(spuBo);

        //直接修改spuDetail
        this.spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetail());
        //获取本次提交的所有sku对象
        List<Sku> allNewSkus=spuBo.getSkus();
        //取出所有的sku的id
        List<Long> allNewIds=new ArrayList<>();
        allNewSkus.forEach(newSku->allNewIds.add(newSku.getId()));

        //数据库中根据spu_id查询的原来的sku
        List<Sku> oldSkus = this.querySkuBySpuId(spuBo.getId());

        //获取原来所有sku的id集合
        List<Long> oldSkuIds = new ArrayList<>();
        oldSkus.forEach(oldSku->oldSkuIds.add(oldSku.getId()));

        //要被下架的sku集合
        List<Sku> toBeDeleteSku = new ArrayList<>();

        //如果提交的sku中不包含，原来的某个sku的id,表示该id的商品被下架
        oldSkus.forEach(oldsku->{
            if(!allNewIds.contains(oldsku.getId())){
                toBeDeleteSku.add(oldsku);
            }
        });

        allNewSkus.forEach(newSku->{
            //提交的sku的id为null，表示是新增的sku，直接保存
            if(newSku.getId()==null){
                newSku.setSpuId(spuBo.getId());
                newSku.setCreateTime(new Date());
                newSku.setLastUpdateTime(newSku.getCreateTime());
                //保存sku
                this.skuMapper.insertSelective(newSku);

                //保存stock表
                Stock stock = new Stock();
                stock.setSkuId(newSku.getId());
                stock.setStock(newSku.getStock());
                this.stockMapper.insertSelective(stock);

            }
            //新来的sku的id在旧的skuId中包含，说明就是要修改的
            else if(oldSkuIds.contains(newSku.getId())){
                newSku.setSpuId(spuBo.getId());
                newSku.setLastUpdateTime(new Date());
                //修改sku
                this.skuMapper.updateByPrimaryKeySelective(newSku);

                Stock stock = new Stock();
                stock.setSkuId(newSku.getId());
                stock.setStock(newSku.getStock());
                //根据sku修改库存
                this.stockMapper.updateByPrimaryKey(stock);

            }
        });
        toBeDeleteSku.forEach(sku->{
            sku.setLastUpdateTime(new Date());
            //表示逻辑下架
            sku.setEnable(false);
            sku.setSpuId(spuBo.getId());
            this.skuMapper.updateByPrimaryKeySelective(sku);
        });
        amqpTemplate.convertAndSend("item.update",spuBo.getId());
    }

    public Spu querySpuById(Long SpuId) {
        return this.spuMapper.selectByPrimaryKey(SpuId);
    }
}
